package com.hserver.docker.service.impl;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateServiceResponse;
import com.github.dockerjava.api.model.*;
import com.hserver.docker.bean.Deploy;
import com.hserver.docker.bean.Registry;
import com.hserver.docker.service.DeployService;
import com.hserver.docker.service.LogService;
import com.hserver.docker.service.RegistryService;
import com.hserver.docker.service.ServiceService;
import com.hserver.docker.utils.DockerUtil;
import cn.hserver.core.ioc.annotation.Autowired;
import cn.hserver.core.ioc.annotation.Bean;
import cn.hserver.core.server.util.ExceptionUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author hxm
 */
@Bean
public class ServiceServiceImpl implements ServiceService {

    @Autowired
    private DeployService deployService;

    @Autowired
    private LogService logService;

    @Autowired
    private RegistryService registryService;

    @Override
    public boolean createService(String name, Integer size, String deployId, String recordId) {

        Registry registry = registryService.getRegistry();
        if (registry == null) {
            logService.add("私有仓库没有建立，请建立私有仓库后重试", recordId);
            return false;
        }
        DockerClient dockerClient = DockerUtil.getDocker();
        try {
            Deploy deploy = deployService.getDeploy(deployId);
//            if (deploy.getServiceId() != null && deploy.getServiceId().trim().length() > 0) {
//                List<Service> exec = dockerClient.listServicesCmd().exec();
//                for (Service service : exec) {
//                    if (service.getId().equals(deploy.getServiceId())) {
//                        ServiceSpec updateServiceSpec = service.getSpec()
//                                .withMode(new ServiceModeConfig().withReplicated(new ServiceReplicatedModeOptions().withReplicas(size)));
//                        dockerClient.updateServiceCmd(deploy.getServiceId(), updateServiceSpec).withVersion(service.getVersion().getIndex());
//                        logService.add(recordId,"服务更新成功");
//                    }
//                }
//            } else {

            List<PortConfig> portsList = new ArrayList<>();
            String ports = deploy.getPorts();
            String[] split = ports.split(",");
            for (String s : split) {
                String[] split1 = s.split(":");
                PortConfig portConfig = new PortConfig()
                        .withPublishMode(PortConfig.PublishMode.host)
                        .withPublishedPort(Integer.parseInt(split1[0]))
                        .withTargetPort(Integer.parseInt(split1[1]))
                        .withProtocol(PortConfigProtocol.TCP);
                portsList.add(portConfig);
            }

            String networkId = null;
            List<Network> exec = dockerClient.listNetworksCmd().exec();
            for (Network network : exec) {
                if (network.getName().equals("hserver-docker")) {
                    networkId = network.getId();
                }
            }
            if (networkId == null) {
                networkId = dockerClient.createNetworkCmd().withName("hserver-docker")
                        .withDriver("overlay")
                        .withIpam(new Network.Ipam()
                                .withDriver("default"))
                        .exec().getId();
            }
            ServiceSpec serviceSpec = new ServiceSpec()
                    .withNetworks(Collections.singletonList(new NetworkAttachmentConfig().withTarget(networkId)))
                    .withEndpointSpec(new EndpointSpec()
                            .withMode(EndpointResolutionMode.VIP)
                            .withPorts(portsList))
                    .withMode(new ServiceModeConfig().withReplicated(
                            new ServiceReplicatedModeOptions()
                                    .withReplicas(size)
                    ))
                    .withTaskTemplate(new TaskSpec()
                            .withContainerSpec(new ContainerSpec()
                                    .withImage(registry.getHost() + ":" + registry.getPort() + "/" + name)));
            CreateServiceResponse exec1 = dockerClient.createServiceCmd(serviceSpec)
                    .exec();
            String id = exec1.getId();
            deploy.setServiceId(id);
            deployService.update(deploy);
            logService.add(recordId, "服务创建成功，ServiceId为：" + id);
//            }
        } catch (Exception e) {
            logService.add(recordId, "服务异常：" + ExceptionUtil.getMessage(e));
            return false;
        } finally {
            try {
                dockerClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

}
